<?php
declare (strict_types = 1);

namespace app;



/**
 * 鹰：自定义Request对象
 * 然后在 config/app.php中加入： 'request_class' => app\Request::class,
 * 使用时 use app\Request;
 */
class Request extends \support\Request
{
    public function get($name = null, $default = null)
    {
        return $this->filter(parent::get($name, $default));
    }

    public function post($name = null, $default = null)
    {
        return $this->filter(parent::post($name, $default));
    }

    public function filter($value)
    {
        if (!$value) {
            return $value;
        }
        if (is_array($value)) {
            array_walk_recursive($value, function(&$item){
                if (is_string($item)) {
                    $item = htmlspecialchars($item);
                }
            });
        } else {
            $value = htmlspecialchars($value);
        }
        return $value;
    }

    public function filter2($data, $filters = 'htmlspecialchars')
    {
        if (!$data) {
            return $data;
        }
        if (is_array($data)) {
            array_walk_recursive($data, function(&$item) use ($filters) {
                if (is_string($item)) {
                    $item = $filters($item);
                }
            });
        } else {
            $data = $filters($data);
        }
        return $data;
    }







//!!!鹰：下面内容修改自 TP 和 我的TP

    //全局过滤规则
    public $filters;


    //鹰：修改自 TP filterData
    //  过滤所有数据
    protected function filterData($data, $filters/*, $name*/, $default)
    {
        // 返回数组
        $filters = $this->getFilter($filters);

        if (is_array($data)) {
            array_walk_recursive($data, [$this, 'filterValue'], $filters, $default);
        } else {
            $this->filterValue($data/*, $name*/, $filters, $default);
        }

        return $data;
    }

    //鹰：修改自 TP
    //  解析过滤器，返回数组
    protected function getFilter($filters): array
    {
        if (is_null($filters)) {
            $filters = [];
        } else {
            $filters = $filters ?: $this->filters;
            if (is_string($filters) && false === strpos($filters, '/')) {
                $filters = explode(',', $filters);
            } else {
                $filters = (array) $filters;
            }
        }

        return $filters;
    }

    /**
     * 鹰：过滤单个数据
     * 递归过滤给定的值
     * @access public
     * @param  mixed $value 键值
     * @param  mixed $key 键名
     * @param  array $filters 过滤方法+默认值
     * @return mixed
     */
    public function filterValue(&$value/*, $key*/, $filters, $default)
    {
        //$default = array_pop($filters);

        foreach ($filters as $filter) {
            if (is_callable($filter)) {
                // 调用函数或者方法过滤
                if (is_null($value)) {
                    continue;
                }

                $value = call_user_func($filter, $value);
            } elseif (is_scalar($value)) {
                if (is_string($filter) && false !== strpos($filter, '/')) {
                    // 正则过滤
                    if (!preg_match($filter, $value)) {
                        // 匹配不成功返回默认值
                        $value = $default;
                        break;
                    }
                } elseif (!empty($filter)) {
                    // filter函数不存在时, 则使用filter_var进行过滤
                    // filter为非整形值时, 调用filter_id取得过滤id
                    $value = filter_var($value, is_int($filter) ? $filter : filter_id($filter));
                    if (false === $value) {
                        $value = $default;
                        break;
                    }
                }
            }
        }

        return $value;
    }

    /**
     * 鹰：简单封装，类似TP的param
     * 获取当前请求的参数
     * @access public
     * @param  string       $name 变量名
     * @param  mixed        $default 默认值
     * @param  string|array $filter 过滤方法
     * @return mixed
     */
    public function param($name = null, $default = null, $filters = ['htmlspecialchars', 'trim'])
    {
        return $this->filterData(parent::input($name, $default), $filters, $default);
        //return $this->filter2(parent::input($name, $default), $filters);
    }

    //鹰：TP 修改而来
    public function has($name = null, $type = 'all')
    {
        if (!in_array($type, ['all', 'get', 'post', 'put', 'patch', 'route', 'delete', 'cookie', 'session', 'env', 'request', 'server', 'header', 'file'])) {
            return false;
        }
        
        /*$param = empty($this->$type) ? $this->$type() : $this->$type;
        if (is_object($param)) {
            return $param->has($name);
        }*/
        $param = $this->$type();

        // 按.拆分成多维数组进行判断
        foreach (explode('.', $name) as $val) {
            if (isset($param[$val])) {
                $param = $param[$val];
            } else {
                return false;
            }
        }

        return true;
        //return $this->filter(parent::input($name));
    }


    
    /**
     * 获取请求的数据
	 * 鹰：获取额外参数和值；
	 * 　　type为 1、2 表示 索引数组（1为 Value 的一维数组，2为key、Value的二维数组），0表示 关联数组
	 *     每条数据组成：
	 *       数组/字符串
	 *     如果是数组：
	 *       $param[0]：要获取的Key
	 *         可以为数组：0为key，1为变量修饰符
	 * 		 $param[1]：默认值；!!!注意，如果默认值为数组，则这个项的值也会转为数组（索引）!!!
	 * 		 $param[2]：过滤函数
	 * 		 $param[3]：替换的新key
	 *     已修改为：如果没有 $param 且没有缺省值，则跳过这个；
	 *     感觉还可以修改 变量修饰符 那部分（去掉 增加变量修饰）
	 * 
	 *     返回：
	 *       索引：二维数组：[[key, 值], [key, 值]。。。]，适用于where
	 *        一维数组[值, 值, 。。。]
	 *       关联：一维关联数组
     * @param array $params
     * @param int $type
     * @return array
     */
    public function getParams(array $params, int $type = 0): array
    {
        $p = [];
        $i = 0;
        foreach ($params as $param) {
            if (!is_array($param))	//鹰：如果不是数组
			{
				//原来的索引数组没有key
                //$p[$suffix == true ? $i++ : $param] = $this->param($param);
				if($type == 0)
					$p[$param] = $this->param($param);
				else if($type == 1)
					$p[$i++] = $this->param($param);
				else
				{
					//修改为 [key, 值]
					$p[$i++] = [$param, $this->param($param)];
				}
            }
			else
			{
                //if (!isset($param[1])) $param[1] = null;
                if (!isset($param[2])) $param[2] = '';
                if (is_array($param[0]))	//如果是数组
				{
					if (!array_key_exists('1', $param))	//如果没有默认值
					{
						if(!$this->has($param[0][0]))	//如果request中没有
							continue;

						$param[1] = null;
					}

					//鹰：如果默认值为数组，则给param加上变量修饰符（/a）；否则手动连接修饰符
                    $name = is_array($param[1]) ? $param[0][0] . '/a' : $param[0][0] . '/' . $param[0][1];
                    $keyName = $param[0][0];
                }
				else
				{
					if (!array_key_exists('1', $param))	//如果没有默认值
					{
						if(!$this->has($param[0]))	//如果request中没有
							continue;

						$param[1] = null;
					}

					//鹰：如果默认值为数组，则给param加上变量修饰符（/a）
                    $name = is_array($param[1]) ? $param[0] . '/a' : $param[0];
                    $keyName = $param[0];
                }

				//原来的索引数组没有key
                //$p[$suffix == true ? $i++ : (isset($param[3]) ? $param[3] : $keyName)] = $this->param($name, $param[1], $param[2]);
				if($type == 0)
					$p[(isset($param[3]) ? $param[3] : $keyName)] = $this->param($name, $param[1], $param[2]);
				else if($type == 1)
					$p[$i++] = $this->param($name, $param[1], $param[2]);
				else
				{
					//修改为 [key, 值]
					$p[$i++] = [isset($param[3]) ? $param[3] : $keyName, $this->param($name, $param[1], $param[2])];
				}
            }
        }
        return $p;
    }

}
